package com.threeti.mecool.core.domain.model.plan.pojo;

import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Transient;
import javax.persistence.Version;
import javax.validation.constraints.NotNull;

import org.codehaus.jackson.annotate.JsonBackReference;
import org.codehaus.jackson.map.annotate.JsonDeserialize;
import org.springframework.beans.factory.annotation.Configurable;

import com.threeti.mecool.core.domain.model.basicdata.biz.ChannelSync;
import com.threeti.mecool.core.domain.model.project.Project;
import com.threeti.mecool.core.domain.model.project.ProjectSalesPromoter;
import com.threeti.mecool.core.domain.model.project.ProjectStore;
import com.threeti.mecool.core.infrastructure.persistence.basicdata.biz.ChannelSyncRepository;
import com.threeti.mecool.core.infrastructure.persistence.plan.PlanJobRepository;
import com.threeti.mecool.core.infrastructure.persistence.project.ProjectRepository;
import com.threeti.mecool.core.infrastructure.persistence.project.ProjectSalesPromoterRepository;
import com.threeti.mecool.core.infrastructure.persistence.project.ProjectStoreRepository;

@Configurable
@Entity
@Table(name = "DM_PLAN_JOB")
public class PlanJob {
    private Long id;
    private Integer version;
    private PlanProject planProject;
    private String storeCode;
    private String storeName;
    private String storeAddress;
    private Job job;
    private Long jobId;
    private Date startTime;
    private Date endTime;
    private int priority;
    private PlanJobRepository repository;
    private ProjectRepository projectRepository;
    private ProjectStoreRepository projectStoreRepository;
    private ProjectSalesPromoterRepository projectSalesPromoterRepository;
    private ChannelSyncRepository channelSyncRepo;
    private String cooperateUser;

	public static PlanJob findById(Long id) {
        return repository().findOne(id);
    }

    //<editor-fold desc="get/set">
    private static PlanJobRepository repository() {
        return new PlanJob().repository;
    }

    @Resource
    public void setRepository(PlanJobRepository repository) {
        this.repository = repository;
    }

    @Resource
    public void setProjectRepository(ProjectRepository projectRepository) {
        this.projectRepository = projectRepository;
    }

    @Resource
    public void setProjectStoreRepository(ProjectStoreRepository projectStoreRepository) {
        this.projectStoreRepository = projectStoreRepository;
    }

    @Resource
		public void setChannelSyncRepo(ChannelSyncRepository channelSyncRepo) {
			this.channelSyncRepo = channelSyncRepo;
		}

    @Resource
    public void setProjectSalesPromoterRepository(ProjectSalesPromoterRepository projectSalesPromoterRepository) {
        this.projectSalesPromoterRepository = projectSalesPromoterRepository;
    }

    @Id
    @GeneratedValue
    public Long getId() {
        return id;
    }

    @Version
    public Integer getVersion() {
        return version;
    }

    @JsonBackReference("planJobs")
    @ManyToOne
    public PlanProject getPlanProject() {
        return planProject;
    }

    public String getStoreCode() {
        return storeCode;
    }

    @Transient
    public String getStoreName() {
        if (storeName == null && storeCode != null) {
            ChannelSync channel = null;
            try {
                channel = channelSyncRepo.findByChannelCode(storeCode);
            } catch (Exception ignore) {
            }
            if (channel != null) {
                storeName = channel.getName();
            }
        }
        return storeName;
    }

    @Transient
    public String getStoreAddress() {
        if (storeAddress == null && storeCode != null) {
        	ChannelSync channel = null;
            try {
              channel = channelSyncRepo.findByChannelCode(storeCode);
            } catch (Exception ignore) {
            }
            if (channel != null) {
                storeAddress = channel.getAddress();
            }
        }
        return storeAddress;
    }

    @ManyToOne
    public Job getJob() {
        if (job == null && jobId != null) {
            job = Job.findById(jobId);
        }
        return job;
    }

    @Transient
    public Long getJobId() {
        if (jobId == null && job != null) {
            jobId = job.getId();
        }
        return jobId;
    }

    @JsonDeserialize(using = SqlTimeDeserializer.class)
    @Temporal(TemporalType.TIME)
    @NotNull
    public Date getStartTime() {
        return startTime;
    }

    @JsonDeserialize(using = SqlTimeDeserializer.class)
    @Temporal(TemporalType.TIME)
    @NotNull
    public Date getEndTime() {
        return endTime;
    }

    public int getPriority() {
        return priority;
    }

    @Transient
    public int getHasScoreTask() {
        Job job = getJob();
        for (Step step : job.getSteps()) {
            if (step.getTask().getActionId() == TaskAction.ID_INPUT_MULTIPLE_SCORE) {
                return 1;
            }
        }
        return 0;
    }

    @Transient
    public List<Map<String, String>> getSales() {
        if (1 == getHasScoreTask()) {
            Project project = projectRepository.findByCode(getPlanProject().getProjectCode());
            if (project != null) {
                List<ProjectStore> projectStores = projectStoreRepository.findByProjectId(project.getId());
                ProjectStore projectStore = null;
                String storeCode = getStoreCode();
                if (storeCode == null) {
                    storeCode = "";
                }
                for (ProjectStore tempProjectStore : projectStores) {
                    if (storeCode.equalsIgnoreCase(tempProjectStore.getChannel().getCode())) {
                        projectStore = tempProjectStore;
                        break;
                    }
                }
                if (projectStore != null) {
                    List<ProjectSalesPromoter> projectSalesPromoters =
                            projectSalesPromoterRepository.findByAssignedStoresId(projectStore.getId());
                    List<Map<String, String>> retList = new ArrayList<Map<String, String>>(projectSalesPromoters.size());
                    for (ProjectSalesPromoter projectSalesPromoter : projectSalesPromoters) {
                        Map<String, String> data = new LinkedHashMap<String, String>(2);
                        retList.add(data);
                        data.put("salesCode", projectSalesPromoter.getSalesPromoter().getCode());
                        data.put("salesName", projectSalesPromoter.getSalesPromoter().getName());
                    }
                    return retList;
                }
            }
        }
        return new ArrayList<Map<String, String>>(0);
    }

    public void setStoreAddress(String storeAddress) {
        this.storeAddress = storeAddress;
    }

    public void setJob(Job job) {
        this.job = job;
    }

    public void setEndTime(Date endTime) {
        this.endTime = endTime;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public void setPlanProject(PlanProject planProject) {
        this.planProject = planProject;
    }

    public void setStartTime(Date startTime) {
        this.startTime = startTime;
    }

    public void setStoreCode(String storeCode) {
        this.storeCode = storeCode;
    }

    public void setStoreName(String storeName) {
        this.storeName = storeName;
    }

    public void setVersion(Integer version) {
        this.version = version;
    }

    public void setJobId(Long jobId) {
        this.jobId = jobId;
    }

    public void setPriority(int priority) {
        this.priority = priority;
    }

    public void setHasScoreTask(int ignore) {}

    public void setSales(List<?> ignore) {}
    
    public void setCooperateUser(String cooperateUser) {
		this.cooperateUser = cooperateUser;
	}
    
    public String getCooperateUser() {
		return cooperateUser;
	}
    //</editor-fold>
}
